using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using System;
using System.Collections.Specialized;
using System.Text;

namespace Microsoft.SqlServer.Management.SqlManagerUI.Scripting
{
using Server = Microsoft.SqlServer.Management.Smo.Server;
	internal class ScriptObjectCommand : ScriptCommand
	{
		private readonly Server server;

		private readonly ObjectScriptedHandler scriptTarget;

		private readonly ScriptActions scriptAction;

		protected ScriptActions ScriptActions
		{
			get
			{
				return this.scriptAction;
			}
		}

		protected ObjectScriptedHandler ScriptTarget
		{
			get
			{
				return this.scriptTarget;
			}
		}

		protected bool Create
		{
			get
			{
				return (this.scriptAction & ScriptActions.Create) > ScriptActions.None;
			}
		}

		protected bool Drop
		{
			get
			{
				return (this.scriptAction & ScriptActions.Drop) > ScriptActions.None;
			}
		}

		protected bool Permission
		{
			get
			{
				return (this.scriptAction & ScriptActions.Permission) > ScriptActions.None;
			}
		}

		protected bool Header
		{
			get
			{
				return (this.scriptAction & ScriptActions.Header) > ScriptActions.None;
			}
		}

		public ScriptObjectCommand(Server server, ObjectScriptedHandler scriptTarget, ScriptActions scriptAction)
		{
			if (scriptTarget == null)
			{
				throw new ArgumentNullException("scriptTarget");
			}
			if (server == null)
			{
				throw new ArgumentNullException("scriptTarget");
			}
			this.scriptTarget = scriptTarget;
			this.server = server;
			this.scriptAction = scriptAction;
		}

		public override void Script(Urn objectToScript, ScriptingOptions scriptOptions)
		{
			if (objectToScript == null)
			{
				throw new ArgumentNullException("objectToScript");
			}
			if (objectToScript.ToString().Length == 0)
			{
				throw new ArgumentException("objectToScript");
			}
			if (scriptOptions == null)
			{
				throw new ArgumentNullException("scriptOptions");
			}
			SqlSmoObject sqlSmoObject = this.GetSqlSmoObject(objectToScript);
			this.ScriptSqlSmoObject(sqlSmoObject, scriptOptions);
		}

		protected virtual SqlSmoObject GetSqlSmoObject(Urn sourceObject)
		{
			return this.server.GetSmoObject(sourceObject);
		}

		protected void ScriptSqlSmoObject(SqlSmoObject smoObject, ScriptingOptions scriptOptions)
		{
			if (smoObject == null)
			{
				throw new ArgumentNullException("smoObject");
			}
			if (this.Create)
			{
				this.ScriptCreate(smoObject, scriptOptions, this.scriptTarget);
			}
			if (this.Drop)
			{
				this.ScriptDrop(smoObject, scriptOptions, this.scriptTarget);
			}
			if (this.Permission)
			{
				this.ScriptPermission(smoObject, scriptOptions, this.scriptTarget);
			}
			if (this.Header)
			{
				this.ScriptHeader(smoObject, scriptOptions, this.scriptTarget);
			}
		}

		protected virtual void ScriptCreate(SqlSmoObject smoObject, ScriptingOptions options, ObjectScriptedHandler scriptTargetHandler)
		{
			StringCollection stringCollection = new StringCollection();
			ReflectionUtilities.InvokeMethod(smoObject, "ScriptCreateInternal", new object[]
			{
				stringCollection,
				options
			});
			scriptTargetHandler(base.GetObjectInfo(smoObject), stringCollection, ScriptActions.Create);
		}

		protected virtual void ScriptDrop(SqlSmoObject smoObject, ScriptingOptions options, ObjectScriptedHandler scriptTargetHandler)
		{
			StringCollection stringCollection = new StringCollection();
			ReflectionUtilities.InvokeMethod(smoObject, "ScriptDropInternal", new object[]
			{
				stringCollection,
				options
			});
			scriptTargetHandler(base.GetObjectInfo(smoObject), stringCollection, ScriptActions.Drop);
		}

		protected virtual void ScriptPermission(SqlSmoObject smoObject, ScriptingOptions options, ObjectScriptedHandler scriptTargetHandler)
		{
			StringCollection stringCollection = new StringCollection();
			ReflectionUtilities.InvokeMethod(smoObject, "AddScriptPermission", new object[]
			{
				stringCollection,
				options
			});
			scriptTargetHandler(base.GetObjectInfo(smoObject), stringCollection, ScriptActions.Permission);
		}

		protected virtual void ScriptHeader(SqlSmoObject smoObject, ScriptingOptions options, ObjectScriptedHandler scriptTargetHandler)
		{
			options.IncludeHeaders = true;
			StringBuilder stringBuilder = new StringBuilder();
			ReflectionUtilities.InvokeMethod(smoObject, "ScriptIncludeHeaders", new object[]
			{
				stringBuilder,
				options,
				smoObject.Urn.Type
			});
			StringCollection stringCollection = new StringCollection();
			stringCollection.Add(stringBuilder.ToString());
			scriptTargetHandler(base.GetObjectInfo(smoObject), stringCollection, ScriptActions.Header);
		}
	}
}
